package org.columba.mail.gui.table.selection;

import java.util.LinkedList;
import java.util.ListIterator;

import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.tree.TreePath;

import org.columba.api.command.ICommandReference;
import org.columba.api.selection.ISelectionListener;
import org.columba.api.selection.SelectionChangedEvent;
import org.columba.core.selection.SelectionHandler;
import org.columba.mail.command.MailFolderCommandReference;
import org.columba.mail.folder.IMailFolder;
import org.columba.mail.gui.socialnet.selection.VertexSelectionChangedEvent;
import org.columba.mail.gui.table.IMessageNode;
import org.columba.mail.gui.table.model.MessageNode;
import org.columba.mail.gui.tree.selection.TreeSelectionChangedEvent;

import com.deruan.hotcore.resource.gui.tree.ResourceTreeNode;
import com.deruan.hotcore.resource.table.IResourceTableController;

public class ResourceTableSelectionHandler extends SelectionHandler implements
ListSelectionListener, ISelectionListener
{
	public static final String HANDLER_ID = "mail.resourcetable";

	private LinkedList<ResourceTreeNode> messages;

	private IMailFolder folder;

	// if this is set to true, we use the local selection, instead
	// of using the table selection
	private boolean useLocalSelection;

	private MailFolderCommandReference local;

	private IResourceTableController tableController;
	/**
	 * @param id
	 */
	public ResourceTableSelectionHandler(IResourceTableController tableController) {
		
		super(ResourceTableSelectionHandler.HANDLER_ID);

		this.tableController = tableController;

		tableController.getListSelectionModel().addListSelectionListener(this);

		messages = new LinkedList<ResourceTreeNode>();

		useLocalSelection = false;
	}

	/**
	 * 
	 * @see org.columba.core.gui.util.SelectionHandler#getSelection()
	 */
	public ICommandReference getSelection() {
		if (useLocalSelection == true) {
			return local;
		}

		MailFolderCommandReference reference = new MailFolderCommandReference(folder, getUidArray());

		return reference;
	}

	/**
	 * 
	 * @see org.columba.core.gui.util.SelectionHandler#setSelection(ICommandReference)
	 */
	public void setSelection(ICommandReference selection) 
	{
		MailFolderCommandReference ref = (MailFolderCommandReference) selection;

		folder = (IMailFolder) ref.getSourceFolder();

		useLocalSelection = false;
	}

	private Object[] getUidArray() {
		Object[] result = new Object[messages.size()];
		ListIterator it = messages.listIterator();

		int i = 0;

		while (it.hasNext()) {
			result[i++] = ((ResourceTreeNode) it.next()).getResourceBean();
		}

		return result;
	}

	/**
	 * 
	 * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
	 */
	public void valueChanged(ListSelectionEvent e) {

		useLocalSelection = false;

		// user is still manipulating the selection
		if (e.getValueIsAdjusting() == true) {
			return;
		}

		messages = new LinkedList<ResourceTreeNode>();

		ListSelectionModel lsm = (ListSelectionModel) e.getSource();

		if (lsm.isSelectionEmpty()) {
			// no rows are selected

		} else {
			int[] rows = tableController.getSelectedRows();

			for (int i = 0; i < rows.length; i++) {
				TreePath path = tableController.getPathForRow(rows[i]);
				if ( path == null ) continue;
				
				ResourceTreeNode node = (ResourceTreeNode) path.getLastPathComponent();
				messages.add(node);
			}
		}

		fireSelectionChanged(new ResourceTableSelectionChangedEvent(folder,
				getUidArray()));

	}

	public void setLocalReference(MailFolderCommandReference r) {
		this.local = r;

		useLocalSelection = true;
	}

	/**
	 * 
	 * @see org.columba.core.gui.util.ISelectionListener#connectionChanged(org.columba.core.gui.util.SelectionChangedEvent)
	 */
	public void selectionChanged(SelectionChangedEvent e) {
		if(e instanceof TreeSelectionChangedEvent)
		{
			if (((TreeSelectionChangedEvent) e).getSelected().length > 0) 
			{
				folder = ((TreeSelectionChangedEvent) e).getSelected()[0];
			}
			else {
				folder = null;
			}
		}
		else if(e instanceof VertexSelectionChangedEvent)
		{
			folder = ((VertexSelectionChangedEvent)e).getSelectedFolder();
		}
	}
}
